/*
   Set.cpp
   T3nsors
 
   Created by Michael Barriault on 10-09-29.
   Copyright 2010 MikBarr Studios. All rights reserved.
 
 */

#include "Set.h"
#include <T3nsors/Macros.h>
#include <cstdlib>
#include <cstdio>

T3::Set::Set() {
	return;
}

T3::Set::Set(int iN, int is, int iv) {
	*this = T3::Set(Domain(1,0,0.,0.),iN,is,iv);
}

T3::Set::Set(T3::Domain iO, int iN, int is, int iv) {
	O = iO;
	s = is;
	v = iv;
	N = iN;
	aS.assign(s, T3::Scalar(O));
	aV.assign(v, T3::Vector(O,N));
}

T3::Scalar& T3::Set::S(int i) {
	return aS.at(i);
}

T3::Vector& T3::Set::V(int i) {
	return aV.at(i);
}

T3::Set& T3::Set::operator+=(T3::Set& x) {
	CheckDims(*this, x);
	FOR(l,s) FORO aS.at(l)[o] += x.S(l)[o];
	FOR(l,v) FOR(n,N) FORO aV.at(l)(n)[o] += x.V(l)(n)[o];
	return *this;
}

T3::Set LinCom(double a, T3::Set w, double b, T3::Set x) {
	CheckDims(w, x);
	T3::Set v(w.O,w.N,w.s,w.v);
	FOR(n,v.s) v.S(n) = LinCom(a, w.S(n), b, x.S(n));
	FOR(n,v.v) v.V(n) = LinCom(a, w.V(n), b, x.V(n));
	return v;
}

T3::Set LinCom(double a, T3::Set w, double b, T3::Set x, double c, T3::Set y) {
	CheckDims(w, x);
	CheckDims(x, y);
	T3::Set v(w.O,w.N,w.s,w.v);
	FOR(n,v.s) v.S(n) = LinCom(a, w.S(n), b, x.S(n), c, y.S(n));
	FOR(n,v.v) v.V(n) = LinCom(a, w.V(n), b, x.V(n), c, y.V(n));
	return v;
}

T3::Set LinCom(double a, T3::Set w, double b, T3::Set x, double c, T3::Set y, double d, T3::Set z) {
	CheckDims(w, x);
	CheckDims(x, y);
	CheckDims(y, z);
	T3::Set v(w.O,w.N,w.s,w.v);
	FOR(n,v.s) v.S(n) = LinCom(a, w.S(n), b, x.S(n), c, y.S(n), d, z.S(n));
	FOR(n,v.v) v.V(n) = LinCom(a, w.V(n), b, x.V(n), c, y.V(n), d, z.V(n));
	return v;
}

void CheckDims(T3::Set x, T3::Set y) {
	CheckDims(x.O, y.O);
	if ( x.s != y.s or x.v != y.v or x.N != y.N )
		exit(-1);
}

